﻿/*矩阵能常有三要素，元素，行数和列数，而线性代数基于其上
 * 定义了加，减，乘，除，求逆，转置等，所以该矩阵类也实现
 * 了这些基本的动算和属性，并对其定度的运算进行了相应的运
 * 算符操作，使其可以像比如int,float等基本数据类型那样动
 * 算，大大减小了矩阵运算的难度，使代码更加简洁，明了。
 * property:
 * 		line:矩阵的行数目
 * 		clum:矩阵的列数目
 * 		data:矩阵的数据指针
 * methods:
 * 		......
 */
#ifndef _MATH_METRIC_H_
#define _MATH_METRIC_H_

#include <stdlib.h>
#include <math.h>
#include <assert.h>

class MathMetric
{
private:
	//矩阵的行数
	unsigned int line;
	//矩阵的列数
	unsigned int clum;
	//矩阵的元素数据的开头指针
	double* data;

public://下面为构造函数和析构函数
	//空构造函数
	MathMetric();
	//另外一个构造函数
	MathMetric(double*,unsigned int,unsigned int);
	//析构函数，主要完成内存的释放
	virtual ~MathMetric();

public://以下全为静态函数，可以不构造类直接调用
	static double* add(double*,unsigned int,unsigned int,double*,unsigned int,unsigned int);
	static double* sub(double*,unsigned int,unsigned int,double*,unsigned int,unsigned int);
	static double* multiple(double*,unsigned int,unsigned int,double*,unsigned int,unsigned int);
	static double* devide(double*,unsigned int,unsigned int,double*,unsigned int,unsigned int);
	static bool inverse(double* metric1,int n);
	static bool reverse(double* data,unsigned int line,unsigned int colum);

public://重载"+","-","*","/"等各种运算符，以后可以像普通数据类型那样对矩阵进行运算
	MathMetric & operator *(MathMetric&);
	MathMetric & operator -(MathMetric&);
	MathMetric & operator -(void);
	MathMetric & operator +(MathMetric &);
	MathMetric & operator /(MathMetric &);

public://以下为矩阵类的各种属性的获取和设置成员函数
	//求矩阵的转置,此作为内部成员函数
	bool reverse(void);
	//获取数据
	void set_data(double*);
	//获取矩阵元素数据指针
	double* get_data(void);
	//设置矩阵的列数
	void set_colum(unsigned int);
	//设置矩阵的行数
	void set_line(unsigned int);
	//获取矩阵的列数
	unsigned get_colum(void);
	//获取矩阵的行数
	unsigned get_line(void);
	//将矩阵元素以长字符串的形式输出到stdout
	bool print();
};


/**********************************************************
函数名：operator *
功能：重载一个常数与矩阵的"*"运算符
入口参数：k:一个基本数据类型 Metric1:一个任意矩阵
出口参数：*result：一个矩阵，它存储了"*"符号的运算结果
说明：将些函数在头文件中实现，而不是在单独的C文件中实现是有
	  原因的，这样可以不对每种情况具现化，可以杜绝连接错误
**********************************************************/

template <class Type>
MathMetric & operator *(Type k,MathMetric &Metric1)
{
	MathMetric *result;
	double *res;
	res=Metric1.get_data();
	result=new MathMetric(res,Metric1.get_line(),Metric1.get_colum());
	res=result->get_data();
	for(unsigned int i=0;i<Metric1.get_colum()*Metric1.get_line();i++)
		res[i]*=k;
	return *result;
}

#endif
